<template>
  <div class="h-full w-9/10 lg:w-2/3 mx-auto">
    <a-form
      class="relative transform top-1/5"
      :model="models"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 14, push: 1 }"
      autocomplete="off"
      :hide-required-mark="false"
    >
      <a-form-item label="项目ID" name="projectId" v-bind="validateInfos.projectId">
        <a-input
          v-model:value="models.projectId"
          allow-clear
          class="children:tracking-widest"
          placeholder="6位Axure项目id"
        >
          <template #suffix>
            <a-tooltip title="Axure 项目地址的三级域名" overlay-class-name="text-sm!">
              <span class="i-mdi:information-variant-circle-outline text-lg cursor-help"></span>
            </a-tooltip>
          </template>
        </a-input>
      </a-form-item>

      <a-form-item label="Git 地址" name="gitPath" v-bind="validateInfos.gitPath">
        <a-input
          v-model:value="models.gitPath"
          allow-clear
          class="children:tracking-widest"
          placeholder="https 形式; 若指定, 则需选择项目父级目录"
          :disabled="gitDisable"
          @change="onGitChange"
        >
          <template #suffix>
            <a-tooltip overlay-class-name="text-sm!">
              <template #title>
                <span>
                  将会自动在父级目录下通过
                  <span class="mx-0.5 bg-[#141414] px-1 py-0.5 rounded-md">git clone</span>
                  命令拉取项目
                </span>
              </template>
              <span class="i-mdi:information-variant-circle-outline text-lg cursor-help"></span>
            </a-tooltip>
          </template>
        </a-input>
      </a-form-item>

      <a-form-item label="项目父级目录" name="fatherDir" v-bind="validateInfos.fatherDir">
        <div class="w-full flex justify-between space-x-4">
          <a-input
            v-model:value="models.fatherDir"
            class="children:tracking-widest"
            placeholder="请选择"
            allow-clear
            :disabled="fatherDsiable"
          ></a-input>
          <a-button type="primary" :disabled="fatherDsiable" @click="selectFatherPath">选择</a-button>
        </div>
      </a-form-item>

      <a-form-item label="项目根目录" name="viewPath" v-bind="validateInfos.workspace">
        <div class="w-full flex justify-between space-x-4">
          <a-input
            v-model:value="models.workspace"
            class="children:tracking-widest"
            allow-clear
            :disabled="workspaceDisable"
            placeholder="若指定 Git 地址, 则该项不必填"
          >
            <template #suffix>
              <a-tooltip overlay-class-name="text-sm!">
                <template #title>
                  <ul class="list-disc list-inside">
                    <li>
                      将会在项目根目录下创建名为
                      <span class="mx-0.5 bg-[#141414] px-1 py-0.5 rounded-md">records</span>
                      的文件夹, 用于存储相关信息
                    </li>
                    <li class="align-text-top">
                      会在 <span class="mx-0.5 bg-[#141414] px-1 py-0.5 rounded-md">views</span> 或
                      <span class="mx-0.5 bg-[#141414] px-1 py-0.5 rounded-md">pages</span>
                      文件夹下创建目录及页面
                    </li>
                  </ul>
                </template>
                <span class="i-mdi:information-variant-circle-outline text-lg cursor-help"></span>
              </a-tooltip>
            </template>
          </a-input>
          <a-button type="primary" :disabled="workspaceDisable" @click="selectWorkplace">选择</a-button>
        </div>
      </a-form-item>

      <a-form-item :wrapper-col="{ offset: 7, span: 14 }">
        <div class="flex items-center space-x-3">
          <a-button
            class="w-3/4 tracking-widest"
            type="primary"
            :loading="loading"
            @click.prevent="chooseModeToEnter"
          >
            <span v-if="!models.workspace">生成预备菜单列表</span>
            <span v-else>进入开发模式</span>
          </a-button>
          <a-button
            class="flex-1 space-x-1 flex items-center justify-center"
            :loading="loading2"
            :disabled="continueDisabled"
            @click="gotoContinueMode"
          >
            <span>继续</span>
            <span class="i-mdi-arrow-right text-base"></span>
          </a-button>
        </div>
      </a-form-item>
    </a-form>
  </div>
</template>

<script setup lang="ts" name="IForm">
import type { Rule } from 'ant-design-vue/es/form'
import type { ChangeEvent } from 'ant-design-vue/es/_util/EventInterface'
import { message, Form } from 'ant-design-vue'
import { useGlobalStore } from '@/store'
import useState from '@/hooks/useState'
import { useSelectPath, usePathExist } from '@/hooks/useFile'
import useInteraction from '@/hooks/useInteraction'

const emit = defineEmits<{
  (event: 'processing'): void
  (event: 'done'): void
}>()

const { useForm } = Form

type Model = typeof models

const store = useGlobalStore()

const models = reactive({
  projectId: store.projectId,
  workspace: store.workspace,
  gitPath: '',
  fatherDir: ''
})

const gitDisable = ref(false)
const fatherDsiable = ref(false)
const workspaceDisable = ref(false)
const continueDisabled = computed(() => {
  return !!models.gitPath || !models.workspace || (!!models.workspace && !/^\w:/i.test(models.workspace))
})

const onGitChange = (e: ChangeEvent) => {
  const { value } = e.target

  const urlReg = /^https:\/\//
  const isValid = urlReg.test(value as string)

  rules.fatherDir[0].required = isValid
  rules.workspace[0].required = !isValid

  workspaceDisable.value = isValid
  isValid && clearValidate('workspace')
}

const gitMode = () => {
  models.workspace = ''
  workspaceDisable.value = true
  gitDisable.value = false
  fatherDsiable.value = false
}
const workspaceMode = () => {
  models.fatherDir = models.gitPath = ''
  workspaceDisable.value = false
  gitDisable.value = true
  fatherDsiable.value = true
}

const fDirValidator = (_: Rule, value: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    if (models.gitPath && !value) reject('请选择项目父级目录')
    else resolve()
  })
}

const workspaceValidator = (_: Rule, value: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    if (!models.gitPath && !value) {
      reject('请选择项目根路径')
    } else resolve()

    gitDisable.value = !!value
    fatherDsiable.value = !!value
  })
}

const rules: Record<keyof Model, Rule[]> = reactive({
  projectId: [{ required: true, message: '请输入 Axure 项目 ID' }],
  gitPath: [{ pattern: /^https:\/\//, message: '请输入正确的 git https 地址', trigger: 'change' }],
  fatherDir: [{ required: false, validator: fDirValidator, trigger: 'change' }],
  workspace: [{ required: true, validator: workspaceValidator, trigger: 'change' }]
})
const { validate, validateInfos, clearValidate } = useForm(models, rules)

// 如果有 git 地址，则拉取远程项目
const fetchGit = async (closeLoading: () => void) => {
  const { error } = await useInteraction<{ error: string }>({
    type: 'file',
    eventName: 'git',
    data: {
      url: models.gitPath,
      father: models.fatherDir
    }
  })

  closeLoading()

  const projectName = models.gitPath.split('/').at(-1)?.split('.')[0]

  if (error as string) {
    if ((error as string).includes('已存在')) {
      workspaceMode()
      message.info({ content: `已切换为根目录模式`, duration: 5 })
    }
    throw new Error(`拉取失败: ${error}`)
  } else {
    message.success({ content: `拉取成功, 已在父目录下创建项目 ${projectName}`, duration: 5 })
    return `${models.fatherDir}\\${projectName}`
  }
}

const selectFatherPath = async () => {
  const { path } = await useSelectPath()

  if (!path) return

  models.fatherDir = path
}

const selectWorkplace = async () => {
  const { path } = await useSelectPath()

  if (!path) return

  models.workspace = path
}

// 拉取了 git, 但项目初始化还未完成, 不转到开始编辑页，而是继续编辑目录数据
// const [forceToNext, setForceToNext] = useState(false)
// 主按钮的加载
const [loading, setLoading] = useState(false)
// 继续按钮的加载
const [loading2, setLoading2] = useState(false)
const router = useRouter()

const wrapValidate = (callback: (data: Model) => any) => {
  return async () => {
    try {
      const data = (await validate()) as Model
      store.projectId = data.projectId
      store.workspace = data.workspace = data.gitPath ? '' : data.workspace

      emit('processing')

      await callback(data)
      // eslint-disable-next-line no-empty
    } catch (e: any) {
      const hasErrorText = e?.message ?? e
      hasErrorText && message.error(hasErrorText, 5)
    }
  }
}

const chooseModeToEnter = () => {
  if (models.gitPath && models.fatherDir) {
    gotoGitMode()
  } else if (models.workspace) {
    gotoDevelopMode()
  } else {
    try {
      validate()
      // eslint-disable-next-line no-empty
    } catch (error) {}
  }
}

// 首次进入，通过 Git 获取，进入初始模式
const gotoGitMode = wrapValidate(async () => {
  setLoading(true)

  gitMode()

  const hideMsg = message.loading('正在拉取 git...', 0)
  const workspace = await fetchGit(hideMsg)
  store.workspace = models.workspace = workspace

  setLoading(false)

  emit('done')
})

// 步骤未结束，进入继续编辑模式, 通过点击继续按钮开始
const gotoContinueMode = wrapValidate(async () => {
  setLoading2(true)

  const { isExist } = await usePathExist({
    path: store.workspace
  })

  setLoading2(false)

  await nextTick()

  if (!isExist) {
    message.warn('项目目录不存在', 5)
  } else {
    emit('done')
  }
})

// 直接进入开发
const gotoDevelopMode = wrapValidate(async () => {
  setLoading(true)

  const { isExist, content } = await usePathExist({
    path: `${store.treePath}\\${store.translatedFile}`,
    returnText: true
  })

  setLoading(false)

  await nextTick()

  if (isExist) {
    store.treeToTranslate = JSON.parse(content)

    router.push({ name: 'startup' })
  } else {
    message.warn('未检测到翻译后的目录数据', 5)
  }
})
</script>
